/************************************************************************
 *
 * mutex.h
 *
 * (c) Copyright 2001-2004 Analog Devices, Inc.  All rights reserved.
 * $Revision: 1.4.4.3 $
 ************************************************************************/

#pragma once
#ifndef __NO_BUILTIN
#pragma system_header /* mutex.h */
#endif

#ifndef __MUTEX_H
#define __MUTEX_H

#include <stdlib.h>
#include <stdio.h>

#if defined(__cplusplus)
		/* MULTITHREAD PROPERTIES */
#if defined(_ADI_THREADS) || defined(__ADI_MULTICORE)

namespace VDK
{
  class   Mutex;
  void    InitMutex    (Mutex *, unsigned int size, bool history);
  void    DeInitMutex  (Mutex *pMutex);

#pragma linkage_name _AcquireMutex__3VDKF7MutexID
  void    AcquireMutex (Mutex *idMutex);

#pragma linkage_name _ReleaseMutex__3VDKF7MutexID
  void    ReleaseMutex (Mutex *idMutex);

}; // namespace VDK

_STD_BEGIN

// These are defined in your CRT with a suitable constructor called.
#define _LOCK_LOCALE 0
#define _LOCK_STREAM 1
#define _LOCK_MALLOC 2
#define _MAX_LOCK 3

extern "C" {
_Pragma("linkage_name _DestroySemaphore__3VDKF11SemaphoreID")
 void _DESTROY_SEMAPHORE(int);
} 

#define VDK_MUTX_SIZE (5*sizeof(int))

    // CLASS _Mutex
class _IOMutex
  { // lock under program control
public:
  _IOMutex() {
      m_vdkMutex = (VDK::Mutex *) malloc (VDK_MUTX_SIZE);
      VDK::InitMutex(m_vdkMutex, VDK_MUTX_SIZE, 0 /*False*/);
  };
  ~_IOMutex() {
      VDK::DeInitMutex(m_vdkMutex);
      free(m_vdkMutex);
  };
  void _Lock();
  void _Unlock();
private:
  VDK::Mutex *m_vdkMutex;
};

extern _IOMutex  _cIOLock;

    // CLASS _Lockit
class _Lockit
  { // lock while object in existence -- MUST NEST
public:
  explicit _Lockit();
  explicit _Lockit(int);
  ~_Lockit();
  };

class _LockitIO
{
  public:
    explicit _LockitIO();
    ~_LockitIO();
};

_STD_END

#else /* ! _ADI_THREADS */

 /*required by Dinkumware C sources*/
 #define _PUSH_UNSCHEDULED_REGION (void)0
 #define _POP_UNSCHEDULED_REGION (void)0
 #define _LOCK_LOCALE	0
 #define _LOCK_MALLOC	1
 #define _LOCK_STREAM	2
 #define _MAX_LOCK		3	/* one more than highest lock number */

_STD_BEGIN
		// CLASS _Lockit
class _Lockit
	{	// lock while object in existence -- MUST NEST
public:
   #define _LOCKIT(x)
   #pragma always_inline
	explicit inline _Lockit() 
        {	
          // do nothing
        }

   #pragma always_inline
	explicit inline _Lockit(int) 
        {	 
          // do nothing
        }

   #pragma always_inline
	inline ~_Lockit() 
        { 
          // do nothing
        }
	};
class _LockitIO
	{
   #pragma always_inline
	explicit inline _LockitIO()
	{
	}
   #pragma always_inline
	inline ~_LockitIO()
	{
	}
	};

_STD_END
#endif /* _ADI_THREAD */

#else  /* C Only */

#if !defined(_ADI_THREADS) && !defined(__ADI_MULTICORE)
 #define _PUSH_UNSCHEDULED_REGION(x) (void)0
 #define _POP_UNSCHEDULED_REGION(x) (void)0
 #define _PUSH_C_IO_ATOMIC_SECTION() (void)0
 #define  _POP_C_IO_ATOMIC_SECTION() (void)0 
#ifndef _BUILDING_ADI_MC_ROUTINES
 #define _Lockfileatomic(x) _PUSH_C_IO_ATOMIC_SECTION()
 #define _Unlockfileatomic(x) _PUSH_C_IO_ATOMIC_SECTION()
#endif
 #define _LOCK_LOCALE	0
 #define _LOCK_MALLOC	1
 #define _LOCK_STREAM	2
 #define _MAX_LOCK	3	/* one more than highest lock number */

#else /* _ADI_THREAD */

extern void *_cIOLock;
extern void _Lock__8_IOMutexFv(void *);
extern void _Unlock__8_IOMutexFv(void *);

#define _PUSH_C_IO_ATOMIC_SECTION() _Lock__8_IOMutexFv((void *)(&_cIOLock))
#define _POP_C_IO_ATOMIC_SECTION() _Unlock__8_IOMutexFv((void *)(&_cIOLock)) 
#ifndef _BUILDING_ADI_MC_ROUTINES
#define _Lockfileatomic(x) _PUSH_C_IO_ATOMIC_SECTION()
#define _Unlockfileatomic(x) _POP_C_IO_ATOMIC_SECTION()
#endif
#define _LOCK_MALLOC 0
#define _LOCK_LOCALE 1
#define _LOCK_STREAM 2
#define _LOCK_FILEIO 3
#define _MAX_LOCK 4

#endif /* _ADI_THREADS */

#endif /* __cplusplus */

#endif /* __MUTEX_DEFINED */

/* end of file */

